package com.wmh.baseservice.common.redis.mq.core.interceptor;

import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.wmh.baseservice.common.redis.mq.core.message.RedisMessageBase;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;

/**
 * Redis 消息拦截器工厂
 *
 * @author 审心
 */
public class RedisMessageInterceptorFactory {

    /**
     * 支持一对多的 map
     * key 为 消息体类对象
     * value 为 拦截器对象
     */
    private final Multimap<Class<? extends RedisMessageBase>, RedisMessageInterceptor<RedisMessageBase>> interceptorMultimap = HashMultimap.create();


    /**
     * 添加 消息拦截器
     *
     * @param k 消息体类对象
     * @param v 消息拦截器对象
     */
    @SafeVarargs
    public final void put(Class<? extends RedisMessageBase> k, RedisMessageInterceptor<RedisMessageBase>... v) {
        interceptorMultimap.putAll(k, Arrays.asList(v));
    }

    /**
     * 获取
     *
     * @param k 消息体类对象
     * @return 对应的消息拦截器
     */
    public Collection<RedisMessageInterceptor<RedisMessageBase>> get(Class<? extends RedisMessageBase> k) {
        return interceptorMultimap.get(k);
    }

    /**
     * 获取排序后
     *
     * @param k 消息体类对象
     * @return 对应的消息拦截器
     */
    public Collection<RedisMessageInterceptor<RedisMessageBase>> getAndSort(Class<? extends RedisMessageBase> k) {
        Collection<RedisMessageInterceptor<RedisMessageBase>> interceptors = get(k);
        CollUtil.sort(interceptors, Comparator.comparingInt(RedisMessageInterceptor::getPriority));
        return interceptors;
    }

    /**
     * 发布前处理
     *
     * @param message 消息体对象
     */
    public void sendBefore(RedisMessageBase message) {
        Collection<RedisMessageInterceptor<RedisMessageBase>> interceptors = getAndSort(message.getClass());
        interceptors.forEach(interceptor -> {
            interceptor.sendBeforeHandler(message);
        });
    }

    /**
     * 发布后处理
     *
     * @param message 消息体对象
     */
    public void sendAfter(RedisMessageBase message) {
        Collection<RedisMessageInterceptor<RedisMessageBase>> interceptors = getAndSort(message.getClass());
        interceptors.forEach(interceptor -> {
            interceptor.sendAfterHandler(message);
        });
    }

    /**
     * 消费前处理
     *
     * @param message 消息体对象
     */
    public void consumeBefore(RedisMessageBase message) {
        Collection<RedisMessageInterceptor<RedisMessageBase>> interceptors = getAndSort(message.getClass());
        interceptors.forEach(interceptor -> {
            interceptor.consumeBeforeHandler(message);
        });
    }

    /**
     * 消费成功处理
     *
     * @param message 消息体对象
     */
    public void consumeSucceed(RedisMessageBase message) {
        Collection<RedisMessageInterceptor<RedisMessageBase>> interceptors = getAndSort(message.getClass());
        interceptors.forEach(interceptor -> {
            interceptor.consumeSucceedHandler(message);
        });
    }

    /**
     * 消费最终处理
     *
     * @param message 消息体对象
     */
    public void consumeFinally(RedisMessageBase message) {
        Collection<RedisMessageInterceptor<RedisMessageBase>> interceptors = getAndSort(message.getClass());
        interceptors.forEach(interceptor -> {
            interceptor.consumeFinallyHandler(message);
        });
    }
}